#-*- coding: utf-8 -*-
#
# Copyright (C) 2007 Ville Leskinen
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

from igCreator.config import *
from igCreator.imagelist import ListenableImageList, ImageBox, ImageListOptions
from igCreator.gallery import ListenableGallery

from PyQt4 import QtCore, QtGui
from ui_QigCreator import Ui_MainWindow

from guilistener import GuiListener
from imageviewer import ImageViewer

class GalleryThread(QtCore.QThread):

	def __init__(self, gallery, parent=None):
		QtCore.QThread.__init__(self, parent)
		self.gallery = gallery

	def run(self):
		self.gallery.create()

class QigCreator(QtGui.QMainWindow, Ui_MainWindow):
	"""Main window of the UI."""

	def __init__(self, parent=None):
		"""Constuctor."""
		QtGui.QMainWindow.__init__(self, parent)

		self.setupUi(self)
		self.listener = GuiListener()

		self._initConnections()

		self.configFile = CfgFileConfig('.igcreator')
		self.imageList = ListenableImageList()
		self.imageviewer = ImageViewer(self)

		self._initOptions()


	def _initConnections(self):
		"""Initializes connections."""

		# actions
		self.connect(self.actionQuit, QtCore.SIGNAL('triggered()'),
					QtCore.SLOT('close()'))
		self.connect(self.actionGenerate, QtCore.SIGNAL('triggered()'),
					self.generate)
		self.connect(self.actionSaveConfig, QtCore.SIGNAL('triggered()'),
					self.saveConfig)
		
		# toolbuttons
		self.connect(self.tbImageDir, QtCore.SIGNAL('clicked()'),
					self.selectImageDir)
		self.connect(self.tbOutputDir, QtCore.SIGNAL('clicked()'),
					self.selectOutputDir)
		self.connect(self.tbPicTemplate, QtCore.SIGNAL('clicked()'),
					self.selectPicTemplate)
		self.connect(self.tbThumbTemplate, QtCore.SIGNAL('clicked()'),
					self.selectThumbTemplate)
		self.connect(self.tbCustomCSS, QtCore.SIGNAL('clicked()'),
					self.selectCustomCSS)

		# LineEdits
		self.connect(self.leImageDir, QtCore.SIGNAL('textChanged(QString)'),
					self.loadImageList)

		# listener
		self.connect(self.listener, QtCore.SIGNAL('EventAdd'), self.eventAdd)
		self.connect(self.listener, QtCore.SIGNAL('EventHappening'), self.updateProgress)
		self.connect(self.listener, QtCore.SIGNAL('Finished'), self.progressFinished)

		# lwImages
		self.connect(self.lwImages, QtCore.SIGNAL('itemActivated(QListWidgetItem *)'),
				self.openImage)

	def _initOptions(self):
		config = self.configFile.config

		if config['heading']:
			self.leHeading.setText(config['heading'])

		imagedir = config['imagedir']
		if imagedir:
			self.leImageDir.setText(imagedir)
			self.imageList.readListFromPath(imagedir)

		if config['outputdir']:
			self.leOutputDir.setText(config['outputdir'])

		if config['pictemplate']:
			self.lePicTemplate.setText(config['pictemplate'])

		if config['thumbtemplate']:
			self.leThumbTemplate.setText(config['thumbtemplate'])

		if config['custom-css']:
			self.leCustomCSS.setText(config['custom-css'])

		if config['filter']:
			filterIndex = self.cbResizeFilter.findText(config['filter'])
			if filterIndex != -1:
				self.cbResizeFilter.setCurrentIndex(filterIndex)
			else:
				print "Invalid filter: %s" % (config['filter'])

		if config['size']:
			self.lePictureSize.setText(config['size'])

		if config['thumbsize']:
			self.leThumbnailSize.setText(config['thumbsize'])


	def selectImageDir(self):
		"""
		Selects image directory using file dialog.
		"""
		directory = self._selectDir(self.leImageDir.text())
		
		if not directory.isEmpty():
			self.leImageDir.setText(directory)
			self.imageList.readListFromPath(str(directory))

	def selectOutputDir(self):
		"""
		Selects output directory using file dialog.
		"""
		directory = self._selectDir(self.leOutputDir.text())

		if not directory.isEmpty():
			self.leOutputDir.setText(directory)

	def selectPicTemplate(self):
		"""
		Selects picture template using file dialog.
		"""
		pictemplate = self._selectFile(self.lePicTemplate.text(), '')

		if not pictemplate.isEmpty():
			self.lePicTemplate.setText(pictemplate)

	def selectThumbTemplate(self):
		"""
		Selects thumbnail template using file dialog.
		"""
		thumbtemplate = self._selectFile(self.leThumbTemplate.text(), '')

		if not thumbtemplate.isEmpty():
			self.leThumbTemplate.setText(thumbtemplate)

	def selectCustomCSS(self):
		"""
		Selects custom CSS-file using file dialog.
		"""
		customcss = self._selectFile(self.leCustomCSS.text(),
									'CSS-files (*.css)')

		if not customcss.isEmpty():
			self.leCustomCSS.setText(customcss)

	def _selectDir(self, defaultdir):
		d = QtGui.QFileDialog.getExistingDirectory(self,
					self.tr("Open Directory"),
					defaultdir)
		return d

	def _selectFile(self, defaultfile, filefilter):
		f = QtGui.QFileDialog.getOpenFileName(self, self.tr("Open File"),
											defaultfile,
											self.tr(filefilter))

		return f

	def saveConfig(self):
		"""
		Asks where user wants to save the configuration file and
		then saves it.
		"""
		fileName = QtGui.QFileDialog.getSaveFileName(self,
					self.tr('Save Configuration File'))
		if not fileName.isEmpty():
			f = open(fileName, 'w')
			f.write('[default]\n')
			cfg = self._getConfig()
			f.write(str(cfg))
			f.close()

	def generate(self):
		"""
		Generates the gallery using these options.
		"""
		self.cfg = self._getConfig()

		picBox = ImageBox()
		picBox.parseString(self.cfg.config['size'])

		if self.cfg.config['thumbsize']:
			thumbBox = ImageBox()
			thumbBox.parseString(self.cfg.config['thumbsize'])
		else:
			thumbBox = ImageBox(width=150)

		ilOpts = ImageListOptions()

		ilOpts.setPicBox(picBox)
		ilOpts.setThumbBox(thumbBox)
		ilOpts.setResizeFilter(self.cfg.config['filter'])

		self.imageList.setOptions(ilOpts)

		self.gallery = ListenableGallery(self.imageList)

		if self.cfg.config['outputdir']:
			self.gallery.setPath(self.cfg.config['outputdir'])

		if self.cfg.config['pictemplate']:
			self.gallery.readPicTemplate(self.cfg.config['pictemplate'])

		if self.cfg.config['thumbtemplate']:
			self.gallery.readThumbTemplate(self.cfg.config['thumbtemplate'])

		if self.cfg.config['heading']:
			self.gallery.setHeading(self.cfg.config['heading'])

		self.gallery.setCSSFile(self.cfg.config['custom-css'])

		self.imageList.addListener(self.listener)
		self.gallery.addListener(self.listener)

		self.progressBar.setValue(0)

		gthread = GalleryThread(self.gallery, self)
		gthread.start()

#		self.listener.finished()

	def eventAdd(self, listener):
		self.progressBar.setMaximum(listener.totalLength)

	def updateProgress(self, listener, event):
		self.progressBar.setValue(listener.done)
		self.teProgress.append(event.message)

	def progressFinished(self, listener):
		self.progressBar.setValue(listener.done)
		self.teProgress.append("Done!")


	def _getConfig(self):
		"""Generates configuration from given options."""
		def getLineEditText(lineEdit):
			t = lineEdit.text()
			if not t.isEmpty():
				s = str(t)
				return s
			else:
				return None
			
		cfg = Config()
		cfg.config['heading'] = getLineEditText(self.leHeading)
		cfg.config['imagedir'] = getLineEditText(self.leImageDir)
		cfg.config['outputdir'] = getLineEditText(self.leOutputDir)
		cfg.config['pictemplate'] = getLineEditText(self.lePicTemplate)
		cfg.config['thumbtemplate'] = getLineEditText(self.leThumbTemplate)
		cfg.config['custom-css'] = getLineEditText(self.leCustomCSS)
		cfg.config['filter'] = str(self.cbResizeFilter.currentText())
		cfg.config['size'] = getLineEditText(self.lePictureSize)
		cfg.config['thumbsize'] = getLineEditText(self.leThumbnailSize)

		return cfg

	def loadImageList(self, directory):
		self.imageList.readListFromPath(str(directory))
		self.lwImages.clear()
		for image in self.imageList.images:
			self.lwImages.addItem(image)


	def openImage(self, lwiImage):
		self.imageviewer.show()
		self.imageviewer.openImage(lwiImage)
